home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / prev / prev.lha / csg.c < prev    next >
C/C++ Source or Header  |  1991-03-11  |  6KB  |  278 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include "art.h"
  4. #include "objs.h"
  5. #include "macro.h"
  6. #include "gram.h"
  7.  
  8. extern hlist    *fhlist;
  9.  
  10. extern hlist    *(*intersects[])();
  11.  
  12. extern attr    *astackp;
  13. extern mats    *mstackp;
  14.  
  15. extern object    *objectinit();
  16.  
  17. /*
  18.  * getcsgobj
  19.  *
  20.  *    instantiate an object, mark it as being in csg and return it
  21.  */
  22. object *
  23. getcsgobj(sym, d)
  24.     symbol    *sym;
  25.     details    *d;
  26. {
  27.     object    *obj;
  28.  
  29.     obj = objectinit(sym, d);
  30.  
  31.     return(obj);
  32. }
  33.  
  34. /*
  35.  * makecsgtree
  36.  *
  37.  *    set up a csg object from its tree and details list.
  38.  */
  39. object *
  40. makecsgtree(tree)
  41.     csgnode    *tree;
  42. {
  43.     register object    *o;
  44.     register csg    *c;
  45.  
  46.     switch (tree->type) {
  47.     case CSG_SUB:
  48.         o = (object *)smalloc(sizeof(object));
  49.         c = o->obj.csgt = (csg *)smalloc(sizeof(csg));
  50.         o->type = CSG_SUB;
  51.         c->leftb = FALSE;
  52.         c->rightb = TRUE;
  53.         c->left = makecsgtree(tree->u.branch.left);
  54.         c->right = makecsgtree(tree->u.branch.right);
  55.         c->left->incsg = ADDED;
  56.         c->right->incsg = SUBTRACTED;
  57.  
  58.                     /* take bounding box of left */
  59.         o->bb = c->left->bb;
  60.         break;
  61.     case CSG_ADD:
  62.         o = (object *)smalloc(sizeof(object));
  63.         c = o->obj.csgt = (csg *)smalloc(sizeof(csg));
  64.         o->type = CSG_ADD;
  65.         c->leftb = TRUE;
  66.         c->rightb = TRUE;
  67.         c->left = makecsgtree(tree->u.branch.left);
  68.         c->right = makecsgtree(tree->u.branch.right);
  69.         c->left->incsg = ADDED;
  70.         c->right->incsg = ADDED;
  71.  
  72.         if (c->left->bb.max[X] > c->right->bb.max[X])
  73.             o->bb.max[X] = c->left->bb.max[X];
  74.         else
  75.             o->bb.max[X] = c->right->bb.max[X];
  76.         if (c->left->bb.max[Y] > c->right->bb.max[Y])
  77.             o->bb.max[Y] = c->left->bb.max[Y];
  78.         else
  79.             o->bb.max[Y] = c->right->bb.max[Y];
  80.         if (c->left->bb.max[Z] > c->right->bb.max[Z])
  81.             o->bb.max[Z] = c->left->bb.max[Z];
  82.         else
  83.             o->bb.max[Z] = c->right->bb.max[Z];
  84.  
  85.         if (c->left->bb.min[X] < c->right->bb.min[X])
  86.             o->bb.min[X] = c->left->bb.min[X];
  87.         else
  88.             o->bb.min[X] = c->right->bb.min[X];
  89.         if (c->left->bb.min[Y] < c->right->bb.min[Y])
  90.             o->bb.min[Y] = c->left->bb.min[Y];
  91.         else
  92.             o->bb.min[Y] = c->right->bb.min[Y];
  93.         if (c->left->bb.min[Z] < c->right->bb.min[Z])
  94.             o->bb.min[Z] = c->left->bb.min[Z];
  95.         else
  96.             o->bb.min[Z] = c->right->bb.min[Z];
  97.         break;
  98.     case CSG_INT:
  99.         o = (object *)smalloc(sizeof(object));
  100.         c = o->obj.csgt = (csg *)smalloc(sizeof(csg));
  101.         o->type = CSG_INT;
  102.         c->leftb = FALSE;
  103.         c->rightb = FALSE;
  104.         c->left = makecsgtree(tree->u.branch.left);
  105.         c->right = makecsgtree(tree->u.branch.right);
  106.         c->left->incsg = ADDED;
  107.         c->right->incsg = ADDED;
  108.  
  109.                             /* take overlap */
  110.         if (c->left->bb.max[X] < c->right->bb.max[X])
  111.             o->bb.max[X] = c->left->bb.max[X];
  112.         else
  113.             o->bb.max[X] = c->right->bb.max[X];
  114.         if (c->left->bb.max[Y] < c->right->bb.max[Y])
  115.             o->bb.max[Y] = c->left->bb.max[Y];
  116.         else
  117.             o->bb.max[Y] = c->right->bb.max[Y];
  118.         if (c->left->bb.max[Z] < c->right->bb.max[Z])
  119.             o->bb.max[Z] = c->left->bb.max[Z];
  120.         else
  121.             o->bb.max[Z] = c->right->bb.max[Z];
  122.  
  123.         if (c->left->bb.min[X] > c->right->bb.min[X])
  124.             o->bb.min[X] = c->left->bb.min[X];
  125.         else
  126.             o->bb.min[X] = c->right->bb.min[X];
  127.         if (c->left->bb.min[Y] > c->right->bb.min[Y])
  128.             o->bb.min[Y] = c->left->bb.min[Y];
  129.         else
  130.             o->bb.min[Y] = c->right->bb.min[Y];
  131.         if (c->left->bb.min[Z] > c->right->bb.min[Z])
  132.             o->bb.min[Z] = c->left->bb.min[Z];
  133.         else
  134.             o->bb.min[Z] = c->right->bb.min[Z];
  135.         break;
  136.     case OBJECT:
  137.         o = getcsgobj(tree->u.sym, (details *)NULL);
  138.         break;
  139.     default:
  140.         fatal("art: illegal type in csgtree.\n");
  141.  
  142.     }
  143.  
  144.     o->nxt = (object *)NULL;
  145.  
  146.     return(o);
  147. }
  148.     
  149. /*
  150.  * csginit
  151.  *
  152.  *    initialise a csg object
  153.  *
  154.  */
  155. object *
  156. csginit(sym, d)
  157.     symbol    *sym;
  158.     details    *d;
  159. {
  160.     details *dl, *nxtdl, *argdt, *otherdt, *nd;
  161.     object    *o;
  162.     surface    s;
  163.     int    sset;
  164.  
  165.     astackp++;
  166.     *astackp = *(astackp - 1);
  167.  
  168.     mstackp++;
  169.     *mstackp = *(mstackp - 1);
  170.     mident4(mstackp->vm);
  171.  
  172.     s = *astackp->s; 
  173.                     /* reverse list */
  174.     argdt = (details *)NULL;
  175.     for (dl = d; dl != (details *)NULL; dl = nxtdl) {
  176.         nxtdl = dl->nxt;
  177.         dl->nxt = argdt;
  178.         argdt = dl;
  179.     }
  180.  
  181.                     /* copy sym list */
  182.     otherdt = (details *)NULL;
  183.     for (dl = sym->u.det->u.csgobj.det; dl != (details *)NULL; dl = dl->nxt) {
  184.         nd = (details *)smalloc(sizeof(details));
  185.         *nd = *dl;
  186.         nd->nxt = otherdt;
  187.         otherdt = nd;
  188.     }
  189.  
  190.     if (argdt == (details *)NULL) {
  191.         argdt = otherdt;
  192.         otherdt = (details *)NULL;
  193.     }
  194.  
  195.     sset = FALSE;
  196.  
  197.     for (dl = argdt; dl != (details *)NULL; dl = nxtdl) {
  198.         switch (dl->type) {
  199.         case COLOUR:
  200.             s.c.r = dl->u.c.r;
  201.             s.c.g = dl->u.c.g;
  202.             s.c.b = dl->u.c.b;
  203.             sset = TRUE;
  204.             break;
  205.         case AMBIENT:
  206.             s.a.r = dl->u.c.r;
  207.             s.a.g = dl->u.c.g;
  208.             s.a.b = dl->u.c.b;
  209.             sset = TRUE;
  210.             break;
  211.         case TEXTURE:
  212.             dl->u.txt->nxt = astackp->txtlist;
  213.             astackp->txtlist = dl->u.txt;
  214.             break;
  215.         case MATERIAL:
  216.             s.ri = dl->u.mat.ri;
  217.             s.kd = dl->u.mat.kd;
  218.             s.ks = dl->u.mat.ks;
  219.             s.ksexp = dl->u.mat.ksexp;
  220.             sset = TRUE;
  221.             break;
  222.         case REFLECTANCE:
  223.             s.refl = dl->u.f;
  224.             sset = TRUE;
  225.             break;
  226.         case TRANSPARENCY:
  227.             s.trans = dl->u.f;
  228.             sset = TRUE;
  229.             break;
  230.         case ABSORPTION:
  231.             s.falloff = dl->u.f;
  232.             sset = TRUE;
  233.             break;
  234.         case ART_TRANSLATE:
  235.             art_translate(dl->u.v.x, dl->u.v.y, dl->u.v.z);
  236.             break;
  237.         case ART_SCALE:
  238.             art_scale(dl->u.v.x, dl->u.v.y, dl->u.v.z);
  239.             break;
  240.         case ART_ROTATE:
  241.             art_rotate(dl->u.rot.ang, dl->u.rot.axis);
  242.             break;
  243.         case ON:
  244.             astackp->options |= dl->u.i;
  245.             break;
  246.         case OFF:
  247.             astackp->options &= ~dl->u.i;
  248.             break;
  249.         case CSG_OBJ:
  250.         case OBJECT:
  251.             break;
  252.         default:
  253.             warning("art: bad detail in csg ignored.\n");
  254.         }
  255.  
  256.         nxtdl = dl->nxt;
  257.         if (nxtdl == (details *)NULL) {
  258.             nxtdl = otherdt;
  259.             otherdt = (details *)NULL;
  260.         }
  261.  
  262.         free(dl);
  263.     }
  264.  
  265.     if (sset) {
  266.         astackp->s = (surface *)smalloc(sizeof(surface));
  267.         *astackp->s = s;
  268.     }
  269.  
  270.     o = makecsgtree(sym->u.det->u.csgobj.tree);
  271.  
  272.     astackp--;
  273.     mstackp--;
  274.  
  275.     return(o);
  276. }
  277.  
  278.